package dxn.nl.file.client.model.codec;

import dxn.nl.file.client.model.dto.TransferMessageConfig;
import dxn.nl.file.client.model.dto.TransferMessageData;
import dxn.nl.file.client.model.dto.TransferMessageDto;
import dxn.nl.file.client.model.serialize.SerializerDispatcher;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageDecoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

/**
 * 自定义信息解码器
 */
public class MessageCodeUtil {
    public static final SerializerDispatcher SERIALIZER_DISPATCHER = new SerializerDispatcher();
    private static final Logger logger = LoggerFactory.getLogger(MessageCodeUtil.class);

    public static TransferMessageDto decode(ByteBuf byteBuf) throws Exception {
        return decode(byteBuf,true);
    }

    public static TransferMessageDto decode(ByteBuf byteBuf,boolean decodeMessageData) throws Exception {
        TransferMessageDto dto = new TransferMessageDto();
        int type = byteBuf.readInt();
        dto.setType(type);
        int metaByteLength = byteBuf.readInt();
        if (metaByteLength > 0) {
            byte[] metaByte = new byte[metaByteLength];
            byteBuf.readBytes(metaByte);
            TransferMessageConfig meta = SERIALIZER_DISPATCHER.deserialize(metaByte, TransferMessageConfig.class);
            dto.setConfig(meta);
        }
        if (byteBuf.isReadable()) {
            if(decodeMessageData)
            {
                int metaDataLength = byteBuf.readInt();
                if(metaDataLength > 0)
                {
                    byte[] metaByte = new byte[metaDataLength];
                    byteBuf.readBytes(metaByte);
                    TransferMessageData data = SERIALIZER_DISPATCHER.deserialize(metaByte, TransferMessageData.class);
                    dto.setMessageData(data);
                }
            }

            byte[] data = ByteBufUtil.getBytes(byteBuf);
            dto.setData(data);
        }
        return dto;
    }

    public static void encode(final ByteBuf out,final TransferMessageDto dto) throws Exception {
        // 写入类型
        out.writeInt(dto.getType());
        // 写入config
        if(dto.getConfig() != null)
        {
            byte[] bytes = SERIALIZER_DISPATCHER.serialize(dto.getConfig());
            out.writeInt(bytes.length);
            if(bytes.length>0)
            {
                out.writeBytes(bytes);
            }
        }
        else {
            // 没有内容也要写入长度
            out.writeInt(0);
        }

        // 写入基本数据
        if(dto.getMessageData() != null)
        {
            byte[] bytes = SERIALIZER_DISPATCHER.serialize(dto.getMessageData());
            out.writeInt(bytes.length);
            if(bytes.length>0)
            {
                out.writeBytes(bytes);
            }
        }
        else {
            // 没有内容也要写入长度
            out.writeInt(0);
        }

        // 如果字节内容有数据的话写入(字节传输时使用)
        if(dto.getData() != null && dto.getData().length>0)
        {
            out.writeBytes(dto.getData());
        }
    }

    public static void encode(final ByteBuf out,int type,TransferMessageConfig config,byte[] otherByte) throws Exception {
        // 写入类型
        out.writeInt(type);
        // 写入config
        if(config != null)
        {
            byte[] bytes = SERIALIZER_DISPATCHER.serialize(config);
            out.writeInt(bytes.length);
            if(bytes.length>0)
            {
                out.writeBytes(bytes);
            }
        }
        else {
            // 没有内容也要写入长度
            out.writeInt(0);
        }

        // 写入剩余的字节，
        if(otherByte != null && otherByte.length>0)
        {
            out.writeBytes(otherByte);
        }
    }
}
